class GameData extends egret.EventDispatcher{
	private _phrase:string
	/**回合数 */
	public curTurn:number
	/**距离 */
	public curDistance:number
	/**决斗双方 */
	public players:Player[]
	
	/**场地卡片 */
	public fieldCards:BaseCard[][][]
	/**轮次 */
	public curRound:0|1
	public userPlayerNum:0|1 = 0
	public cpuPlayerNum:0|1 = 1
	protected user:Player
	protected cpu:CpuPlayer
	public constructor(firstPlayer:0|1=0) {
		super()
		const t = this
		
		t.curTurn = 1
		t.curDistance = 5
		
		t.user = new Player(0)
		t.cpu = new CpuPlayer(1)
		t.players = [t.user, t.cpu]
		t.players[0].testRandom5Hand()
		t.players[0].testRandomWeapon()
		t.players[1].testRandom5Hand()
		t.players[1].testRandomWeapon()
		t.fieldCards = [
			[
				[null, null, null],
				[null, null, null]
			],
			[
				[null, null, null],
				[null, null, null]
			]
		]
		t.curRound = firstPlayer
		t.opPlayer.turnOut()
		t.curPlayer.turnIn()
		t._phrase = GamePhrase.STANDBY
	}

	public gameStart(){
		const t = this
		//cpu放置3张武器卡
		const cpuWeapons = t.cpu.chooseWeaponCard(3)
		for(let i=0;i<3;i++){
			const tmpc = cpuWeapons[i]
			tmpc.isFront = false
			t.fieldCards[1][1][i] = tmpc
			tmpc.moveTo({f:1, i:1, j:i})
		}
		let evt = new egret.Event(PlayEvents.CPU_ACT_FINISH)
		evt.data = {
			player : t.cpuPlayerNum,
			toField : cpuWeapons
		}
		t.dispatchEvent(evt)
	}

	public async cardHandler(card:BaseCard){
		const t = this
		const player = t.players[card.player.index] 
		function delCard(){
			const cp = card.curPlace
			t.fieldCards[cp.f][cp.i][cp.j] = null
		}
		switch(card.type){
			case CardType.WEAPON:
				player.actWeapon --
				delCard()
				break
			case CardType.SKILL:
				player.actSkill --
				delCard()
				break
			case CardType.SET_SHIELD:
				player.actShield --
				break
			case CardType.ACT_SHIELD:
				break
		}		
		return new Promise((resolve, reject)=>{
			setTimeout(resolve, 3000)
		})
	}

	public putCard(card:BaseCard, cp:CardPosition):CardMoveData{
		const t = this
		let player = card.player.index
		let toField:BaseCard[] = []
		let toHand:BaseCard[] = []
		const oriCard = t.fieldCards[cp.f][cp.i][cp.j]
		let p = t.players[card.player.index]
		if(oriCard){
			oriCard.remove()
			const arr = oriCard.type == CardType.WEAPON?p.weapons:p.hand
			arr.push(oriCard)
			toHand.push(oriCard)
			oriCard.isFront = t.userPlayerNum == oriCard.player.index
		}
		card.moveTo(cp)
		t.fieldCards[cp.f][cp.i][cp.j] = card
		card.isFront = card.type == CardType.WEAPON?false:true
		const arr2 = card.type == CardType.WEAPON?p.weapons:p.hand
		arr2.splice(arr2.indexOf(card), 1)
		toField.push(card)

		if(t._phrase == GamePhrase.STANDBY){
			const tmp = t.fieldCards[cp.f][1].indexOf(null)
			if(tmp < 0) t.phrase = GamePhrase.STANDBY_FINISH
		}
		return {player, toField, toHand}
	}

	public getCardOnPlace(cp:CardPosition){
		return this.fieldCards[cp.f][cp.i][cp.j]
	}

	/**获取一张卡的可放置格 */
	public getEnablePlace(card:BaseCard):boolean[][][]{
		const t = this
		let ret = [
			[
				[false, false, false],
				[false, false, false]
			],
			[
				[false, false, false],
				[false, false, false]
			]
		]
		switch(card.type){
			case CardType.WEAPON:
				for(let i=0; i<3; i++){
					ret[0][1][i] = t.fieldCards[0][1][i] == null || t._phrase.indexOf("STANDBY")>=0
				}
				break
			case CardType.ACT_SHIELD:
				if(t._phrase != GamePhrase.DEF_JUDGE){
					//不处于防御阶段时不能发动反应型护盾，其余处理与战术卡相同
					break
				}
			case CardType.SET_SHIELD:
				if((card as SetShieldCard).opSetable){
					for(let i=0; i<3; i++){
						ret[1][0][i] = t.fieldCards[1][0][i] == null
					}
				}
			case CardType.SKILL:
				for(let i=0; i<3; i++){
					ret[0][0][i] = t.fieldCards[0][0][i] == null
				}
				break
		}
		return ret
	}

	public async turnEnd(){
		const t = this
		t.curRound = (1-t.curRound) as (0|1)
		if(t.curRound == 0){
			t.curTurn += 1
			t.curDistance += 1
		}
		t.opPlayer.turnOut()
		t.curPlayer.turnIn()
		t.phrase = GamePhrase.WAIT
	}

	public get curPlayer(){
		return this.players[this.curRound]
	}
	
	public get opPlayer(){
		return this.players[1-this.curRound]
	}

	public get phrase(){
		return this._phrase
	}

	public set phrase(v:string){
		this._phrase = v
		this.dispatchEvent(new egret.Event(PlayEvents.PHRASE_CHANGED))
	}
}

interface CardPosition{
	/** 0|1 */
	f:number,
	/** 0|1 */
	i:number,
	/** 0|1|2 */
	j:number
}

interface CardMoveData{
	player:0|1,
	/**送去墓地的卡 */
	toGrave?:BaseCard[]
	/**加入手牌的卡 */
	toHand?:BaseCard[]
	/**放置到场上的卡 */
	toField?:BaseCard[]
}